#include <purg.h>

extern "C"
{
#include <TestU01.h>
}

#ifndef __BIG_CRUSH
#define FCN   bbattery_SmallCrush
#else
#define FCN   bbattery_BigCrush
#endif

#ifndef PARALLEL
#define PARALLEL 100
#endif

#include <iostream>

template <typename RNG>
unsigned long  getbits ( void * params , void * state )
{
  RNG **cur_rng = reinterpret_cast <RNG **> ( state );
  int &cur_off = *(int *)params;
  unsigned long ret_val;
  cur_rng[cur_off]->get (ret_val);
  cur_off++;
  if ( cur_off == PARALLEL ) cur_off = 0;
//  std::cout << ret_val << std::endl;
  return ret_val;
}

template <typename RNG>
double  getdouble ( void * params , void * state )
{
  RNG **cur_rng = reinterpret_cast <RNG **> ( state );
  int &cur_off = *(int *)params;
  double ret_val;
  cur_rng[cur_off]->get (ret_val , 0 , 1);
  cur_off++;
  if ( cur_off == PARALLEL ) cur_off = 0;
//  std::cout << ret_val << std::endl;
  return ret_val;
}

void writerng ( void * )
{
}

template <typename RNG>
void fillGen ( unif01_Gen *in )
{
  std::cout << "Creating " << PARALLEL << " generators\n";
  RNG ** state = new RNG *[PARALLEL];
  int  * param = new int;
  int  i_one = 1;
  unsigned int ui_one = 1;
  *param = 0;
  for ( int i = 0 ; i != PARALLEL ; i++ )
    state[i] = new RNG ( ui_one , i_one , i );
  in->state = state;
  in->param = param;
  in->name = new char[5];
  strcpy ( in->name , "Bald" );
  in->GetU01 = & getdouble<RNG>;
  in->GetBits = & getbits<RNG>;
  in->Write = &writerng;
}

int main ( int argc , char **argv )
{
  unif01_Gen  rng;
  fillGen<purg::parallel_gen> ( &rng );
  FCN ( &rng );
}
